﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Security.Cryptography;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace DouYin.Open.Platform.Tools
{
    /// <summary>
    /// API工具类。
    /// </summary>
    public class ApiUtils
    {
        public static string Sign(string appKey, string appSecret, string method, string timestamp, string version, string paramJson)
        {
            // 按给定规则拼接参数
            var paramPattern = "app_key" + appKey + "method" + method + "param_json" + paramJson + "timestamp" + timestamp + "v" + version;
            var signPattern = appSecret + paramPattern + appSecret;
            return Hmac(signPattern, appSecret);
        }


        // 计算hmac
        public static string Hmac(string plainText, string appSecret)
        {
            var h = new HMACSHA256(Encoding.UTF8.GetBytes(appSecret));
            var sum = h.ComputeHash(Encoding.UTF8.GetBytes(plainText));

            var sb = new StringBuilder();
            foreach (byte b in sum)
            {
                sb.Append(b.ToString("x2"));
            }
            return sb.ToString();
        }

        public static Dictionary<string, string> GetQueryMap(NameValueCollection query)
        {
            Dictionary<string, string> queryMap = new Dictionary<string, string>();
            if (query != null)
            {
                foreach (var key in query.AllKeys)
                    queryMap[key] = query[key];
            }
            return queryMap;
        }

        public static string GetRequestCharset(string ctype = null)
        {
            string charset = "utf-8";
            if (!string.IsNullOrEmpty(ctype))
            {
                string[] entires = ctype.Split(';');
                foreach (string entry in entires)
                {
                    string _entry = entry.Trim();
                    if (_entry.StartsWith("charset"))
                    {
                        string[] pair = _entry.Split('=');
                        if (pair.Length == 2)
                        {
                            if (!string.IsNullOrEmpty(pair[1]))
                            {
                                charset = pair[1].Trim();
                            }
                        }
                        break;
                    }
                }
            }
            return charset;
        }

        public static long GetTimeStamp(DateTime datetime)
        {
            if (datetime.Kind != DateTimeKind.Utc)
                datetime = datetime.ToUniversalTime();
            var epochTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
            var span = (long)((datetime - epochTime).TotalSeconds);
            return span;
        }

        public static string GetSortStrJson(object obj)
        {
            JsonSerializerSettings setting = new JsonSerializerSettings();
            setting.NullValueHandling = NullValueHandling.Ignore;//null值不序列化
            string strPostData = JsonConvert.SerializeObject(obj, Formatting.None, setting);
            JObject jObject = JObject.Parse(strPostData);
            SortedDictionary<string, object> target = KeySort(jObject);
            strPostData = JsonConvert.SerializeObject(target);
            return strPostData;
        }


        /// <summary>
        /// 按ascii顺序排序json对象的顺序
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static SortedDictionary<string, object> KeySort(JObject obj)
        {
            var res = new SortedDictionary<string, object>();
            foreach (var x in obj)
            {
                if (x.Value is JValue) res.Add(x.Key, x.Value);
                else if (x.Value is JObject) res.Add(x.Key, KeySort((JObject)x.Value));
                else if (x.Value is JArray)
                {
                    var values = (JArray)x.Value;
                    var tmp = new SortedDictionary<string, object>[values.Count];
                    for (var i = 0; i < values.Count; i++)
                    {
                        if (values[i] is JObject)
                            tmp[i] = KeySort((JObject)values[i]);
                    }
                    res.Add(x.Key, tmp);
                }
            }
            return res;
        }
    }
}
